/******************************************************************************
WeightedOutcomes.h

  -Models a set of possible outcomes paired with their respected probability
  weights.
******************************************************************************/

#ifndef __WEIGHTED_OUTCOMES_H__
#define __WEIGHTED_OUTCOMES_H__

#include <set>

/******************************************************************************
A WeightedOutcome is simply a pair consisting of a discreet weight value 
and an outcome identifier.
******************************************************************************/
typedef std::pair<uint32, uint32> WeightedOutcome;

/******************************************************************************
Define a < operator, so we can sort by weight
******************************************************************************/
bool operator<(const WeightedOutcome& lhs, const WeightedOutcome& rhs);

/******************************************************************************
WeightedOutcomes is a set of outcomes, sorted by weight. 
Duplicate weights are not allowed.
******************************************************************************/
typedef std::set<WeightedOutcome> WeightedOutcomes;

/******************************************************************************
Helper functor to find an outcome based an a test value.
Returns true is the operator value is less than the weight (pair::first)
of the test WeightedOutcome.  This signifies a 'hit' of that outcome.
******************************************************************************/
struct Hits
{
private:
    uint32 m_testValue;
public:
    Hits( uint32 testValue ) : m_testValue( testValue )
    {
    }

    bool operator()( const WeightedOutcome& weightedOutcome ) const
    {
        return m_testValue <=  weightedOutcome.first;
    }
};

/******************************************************************************
Helpers to retrieve outcome values.
******************************************************************************/
//These return 0 if the testValue doesn't match any outcome
uint32 getOutcome( const WeightedOutcomes& outcomes, uint32 testValue );
uint32 getOutcome( WeightedOutcomes& outcomes, uint32 testValue );
//These return 'defaultVal' if the testValue doesn't match any outcome
uint32 getOutcome( const WeightedOutcomes& outcomes, uint32 testValue, uint32 defaultVal );
uint32 getOutcome( WeightedOutcomes& outcomes, uint32 testValue, uint32 defaultVal );

#endif //__WEIGHTED_OUTCOMES_H__
